package cn.bluethink.graphical;

import cn.bluethink.utile.ColorUtil;
import cn.bluethink.utile.GraphicalUtil;
import cn.bluethink.view.Graph;
import org.springframework.util.CollectionUtils;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class Polygon extends Graph{
	 /**
     * 存储多边形顶点
     */
    public List<Point> points = new ArrayList<>();

    public Polygon() {
    }

    public Polygon(Polygon polygon) {
        for (Point point : polygon.points){
            points.add(point);
        }
    }
    
    @Override
    public String type() {
        return "polygon";
    }

    @Override
    public int getHandleCount() {
        return points.size();
    }

    @Override
    public Point getHandle(int index) {
        if (!CollectionUtils.isEmpty(points)) {
            return points.get(index);
        } else {
            return new Point(0, 0);
        }
    }

    @Override
    public void draw(Graphics c) {
        int[] xPoints = GraphicalUtil.getXAndY(points).get("x");
        int[] yPoints = GraphicalUtil.getXAndY(points).get("y");
        c.setColor(ColorUtil.getColor());
        c.drawPolygon(xPoints,yPoints,points.size());
    }

    @Override
    public void drawAsSelect(Graphics c) {
    	 int size = points.size();
         if (size < 2) return;

         Color oldColor= c.getColor();
         c.setColor(Color.YELLOW);

        int[] xPoints = GraphicalUtil.getXAndY(points).get("x");
        int[] yPoints = GraphicalUtil.getXAndY(points).get("y");
        c.drawPolygon(xPoints,yPoints,size);
        c.setColor(oldColor);
    }

    @Override
    public int hitTest(Point point) {

        int inOrOut = 0;

        if (points.size() < 3){
            return 0;
        }
        //判断鼠标选中点是否在多边形内 以及选中点还是边
        for (int i = 0;i < points.size() - 1;i++) {

            //取出边界的相邻两个点
            double  startX = points.get(i).getX(),
                    startY = points.get(i).getY(),
                    endX = points.get(i + 1).getX(),
                    endY = points.get(i + 1).getY();

            //选中点
            if(Math.abs(point.getX() - startX) <= SEL_TOLERANCE && Math.abs(point.getY() - startY) <= SEL_TOLERANCE){
                return i + 1;
            }
            if(Math.abs(point.getX() - endX) <= SEL_TOLERANCE && Math.abs(point.getY() - endY) <= SEL_TOLERANCE){
                return i + 2;
            }

            //判断鼠标选中点是否在多边形内部
            if ((startY < point.getY() && endY >= point.getY()) || (startY >= point.getY() && endY < point.getY())) {
                // 线段上与射线 Y 坐标相同的点的 X 坐标
                double x = startX + (point.getY() - startY) * (endX - startX) / (endY - startY);
                // y、x均相同 则表明交点即为此点
                if (x == point.getX()) {
                    return -1;
                }else {//若不在直线上且满足上面判断条件 那么射线和此直线定有交点 交点数加1
                    inOrOut = inOrOut + 1;
                }
            }
        }
        //判断交点数 奇数在多边形内 偶数则反之
        return inOrOut % 2 == 0 ? 0 : -1;
    }

    @Override
    public void moveTo(int dx, int dy) {
        if (!CollectionUtils.isEmpty(points)){
            for (Point point : points){
                point.translate(dx,dy);
            }
        }
    }

    @Override
    public void moveHandleTo(int index, Point point) {
        if(point != null) {
            points.get(index - 1).setLocation(point.getX(), point.getY());
        }
    }

    public List<Point> getPoints() {
        return points;
    }

    public void setPoints(List<Point> points) {
        this.points = points;
    }

    public Point getLastPoint() {
        if (!CollectionUtils.isEmpty(points)) {
            return points.get(points.size() - 1);
        } else {
            return new Point(0, 0);
        }
    }
}
